/* =========================================================================
 *
 *   The traffic processor.
 *
 *   Development by Sedelnikov Alexander (Bigking).
 *
 * =========================================================================
 */

#include "thread.h"
#include <stdio.h>


#ifdef _WIN32
#include <psapi.h>
#else
#endif


//-----------------------------------------------------------------------//
#ifdef _WIN32
DWORD       cthread::get_thread_id() const
{
    return 0;
}
#else
pthread_t   cthread::get_thread_id() const
{
    return thread_id;
}
#endif


//-----------------------------------------------------------------------//
// @todo make error on create thread
int  cthread::thread_run( void )
{

#ifdef _WIN32
    thread_id = CreateThread( NULL,
                              0,
                              __thread_call_function,
                              (void*)this,
                              0,
                              NULL );
#else
    pthread_create( &thread_id, NULL,
                    &__thread_call_function, (void*)this );
#endif
    return 0;
}


//-----------------------------------------------------------------------//
void cthread::thread_close( void )
{
#ifdef _WIN32
    if( thread_id != NULL )
    {
        CloseHandle( thread_id );
        thread_id = NULL;
    }
#else
    if( thread_id != 0 )
    {
        //close( thread_id );
        thread_id = 0;
    }
#endif
}


//-----------------------------------------------------------------------//
#ifdef _WIN32
DWORD __thread_call_function( void *ptr )
{
    cthread *thread = (cthread*)ptr;
    thread->thread_running();
    return NULL;
}
#else
void* __thread_call_function( void *ptr )
{
    cthread *thread = (cthread*)ptr;
    thread->thread_running();
    return NULL;
}
#endif


//-----------------------------------------------------------------------//
//-----------------------------------------------------------------------//
//-----------------------------------------------------------------------//
int  cprocess::get_pid()
{
#ifdef _WIN32
    return GetCurrentProcessId();
#else
    return getpid();
#endif
}


#ifdef _WIN32
bool   cprocess::pid_exist( DWORD id )
{
    DWORD         pids[ 512 ], count = 0;

    EnumProcesses( pids, sizeof( pids ), &count );

    for( int i = 0; i < count; i++ )
    {
        if( id == pids[ i ] )
            return true;
    }

    return false;
}
#else
bool   cprocess::pid_exist( ulong id )
{
    char   path[ 1024 ];

    sprintf( path, "/proc/%ld/exe", id );

    FILE *f = fopen( path, "rb" );
    if( f != NULL )
    {
        fclose( f );
        return true;
    }

    return false;
}
#endif


//-----------------------------------------------------------------------//
//-----------------------------------------------------------------------//
//-----------------------------------------------------------------------//
bool                 ccritical_section::section_init = false;
ccritical_section    ccritical_section::singleton    = ccritical_section();


//-----------------------------------------------------------------------//
ccritical_section::ccritical_section()
{
#ifdef _WIN32
    section_init     = false;
    if( InitializeCriticalSectionAndSpinCount( &c_section, 0 ) )
        section_init = true;
#else
#endif
}


//-----------------------------------------------------------------------//
ccritical_section::~ccritical_section()
{
#ifdef _WIN32
    DeleteCriticalSection( &c_section );
#else
#endif
}


//-----------------------------------------------------------------------//
void ccritical_section::enter()
{
#ifdef _WIN32
    EnterCriticalSection( &singleton.c_section );
#else
#endif
}


//-----------------------------------------------------------------------//
void ccritical_section::leave()
{
#ifdef _WIN32
    LeaveCriticalSection( &singleton.c_section );
#else
#endif
}
